package com.glSto.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;

@RestController
@RequestMapping("/api/oauth")
public class TYSF_APP {
    private static final Logger logger = LoggerFactory.getLogger(TYSF_APP.class);

    // 固定参数与接口地址
    private static final String DEFAULT_CLIENT_ID = "jeibbjlnkmnhkdjcpohpepphnehjhfcjdeafnoedakieaddanodkpmofdcmbofcehojahnjmlcijjilcomjlnjfhckbeppeo";
    private static final String DEFAULT_CLIENT_SECRET = "pbdjbggdgmgbbeodldlnoehfcekehfbcmjpippfplaapncolccjenjoidboknhinbkmpdckkamcnghmb";
    private static final String GRANT_TYPE = "password";
    private static final String TOKEN_URL = "https://oauth.siam.sinopec.com/oauth/interface/token";
    private static final String USER_INFO_URL = "https://oauth.siam.sinopec.com/oauth/interface/getUserInfo";

    // 工具类
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper(); // 用于解析JSON中的access_token


    /**
     * 合并接口：一键获取Token并查询用户信息
     * @param username 明文用户名（必传）
     * @param password 明文密码（必传）
     * @param clientIp 客户端IP（必传）
     * @param clientId 客户端ID（可选，默认使用固定值）
     * @param clientSecret 客户端密钥（可选，默认使用固定值）
     * @return 最终用户信息结果
     */
    @PostMapping("/getTokenAndUserInfo")
    public String getTokenAndUserInfo(
            @RequestParam String username,
            @RequestParam String password,
            @RequestParam String clientIp,
            @RequestParam(required = false, defaultValue = DEFAULT_CLIENT_ID) String clientId,
            @RequestParam(required = false, defaultValue = DEFAULT_CLIENT_SECRET) String clientSecret) {

        // 1. 记录初始请求参数日志
        logger.info("===== 开始合并流程：获取Token并查询用户信息 =====");
        logger.info("接收请求参数 - 明文用户名：{}，客户端IP：{}，clientId：{}", username, clientIp, clientId);


        try {
            // 2. 第一步：调用Token接口获取access_token
            logger.info("===== 第一步：调用Token接口 =====");
            String tokenResponse = getAccessToken(username, password, clientIp, clientId, clientSecret);
            logger.info("Token接口响应内容：{}", tokenResponse);

            // 3. 解析access_token（从Token响应中提取）
            logger.info("===== 解析access_token =====");
            String accessToken = parseAccessToken(tokenResponse);
            logger.info("解析成功 - 脱敏后access_token：{}", maskAccessToken(accessToken));


            // 4. 第二步：调用用户信息接口
            logger.info("===== 第二步：调用用户信息接口 =====");
            String userInfoResponse = getUserInfo(clientId, clientSecret, accessToken);
            logger.info("用户信息接口响应内容：{}", userInfoResponse);


            // 5. 记录流程结束日志
            logger.info("===== 合并流程完成：成功返回用户信息 =====");
            return userInfoResponse;

        } catch (Exception e) {
            // 全程异常捕获与日志记录
            logger.error("===== 合并流程失败 =====", e);
            return "流程失败：" + e.getMessage();
        }
    }


    /**
     * 内部方法：调用Token接口获取响应
     */
    private String getAccessToken(String username, String password, String clientIp, String clientId, String clientSecret) {
        try {
            // 编码用户名密码
            String encodedUsername = Base64Utils.encodeToString(username.getBytes(StandardCharsets.UTF_8));
            String encodedPassword = Base64Utils.encodeToString(password.getBytes(StandardCharsets.UTF_8));
            logger.info("用户名编码后：{}，密码已加密处理", encodedUsername);

            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("client_id", clientId);
            params.add("client_secret", clientSecret);
            params.add("username", encodedUsername);
            params.add("password", encodedPassword);
            params.add("grant_type", GRANT_TYPE);
            params.add("client_ip", clientIp);

            // 发送请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);

            ResponseEntity<String> response = restTemplate.exchange(TOKEN_URL, HttpMethod.POST, request, String.class);
            logger.info("Token接口调用成功，状态码：{}", response.getStatusCodeValue());
            return response.getBody();

        } catch (Exception e) {
            logger.error("Token接口调用失败", e);
            throw new RuntimeException("获取Token失败：" + e.getMessage());
        }
    }


    /**
     * 内部方法：从Token响应中解析access_token
     */
    private String parseAccessToken(String tokenResponse) {
        try {
            JsonNode jsonNode = objectMapper.readTree(tokenResponse);
            if (jsonNode.has("access_token")) {
                return jsonNode.get("access_token").asText();
            } else {
                throw new RuntimeException("Token响应中未包含access_token字段，响应内容：" + tokenResponse);
            }
        } catch (Exception e) {
            logger.error("解析access_token失败", e);
            throw new RuntimeException("解析Token失败：" + e.getMessage());
        }
    }


    /**
     * 内部方法：调用用户信息接口
     */
    private String getUserInfo(String clientId, String clientSecret, String accessToken) {
        try {
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("client_id", clientId);
            params.add("client_secret", clientSecret);
            params.add("access_token", accessToken);

            // 发送请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);

            ResponseEntity<String> response = restTemplate.exchange(USER_INFO_URL, HttpMethod.POST, request, String.class);
            logger.info("用户信息接口调用成功，状态码：{}", response.getStatusCodeValue());
            return response.getBody();

        } catch (Exception e) {
            logger.error("用户信息接口调用失败", e);
            throw new RuntimeException("获取用户信息失败：" + e.getMessage());
        }
    }


    /**
     * 工具方法：脱敏access_token（只显示前6位和后4位）
     */
    private String maskAccessToken(String accessToken) {
        if (accessToken == null || accessToken.length() <= 10) {
            return accessToken;
        }
        return accessToken.substring(0, 6) + "****" + accessToken.substring(accessToken.length() - 4);
    }

}
